using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace EpicBall.ScreenSystem
{
    /// <summary>
    /// Manages the game states in the game
    /// </summary>
    public class GameStack : Microsoft.Xna.Framework.DrawableGameComponent
    {
        private SpriteBatch _spriteBatch;
        private ContentManager _contentManager;
        private Stack<GameScreen> _screens;
        private Vector2 _dimensions;
        private Game _game;
        public GameStack(Game game) : base(game)
        {
            _game = game;
            _contentManager = game.Content;
            _screens = new Stack<GameScreen>();
        }

        public SpriteBatch SpriteBatch
        {
            get { return _spriteBatch; }
        }

        public ContentManager Content
        {
            get { return _contentManager; }
        }

        public Game Game { get { return _game; } }

        public Vector2 Dimensions
        {
            get { return _dimensions; }
        }

        public String GetSavePath
        {
            get
            {
                return Path.Combine(Directory.GetCurrentDirectory(), "EpicBallScores");
            }
        }

        public void AddScreen(GameScreen screen)
        {
            screen.GameStack = this;
            screen.LoadContent();
            _screens.Push(screen);
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();
            Viewport vm = GraphicsDevice.Viewport;
            _dimensions = new Vector2(vm.Width, vm.Height);
        }

        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(GraphicsDevice);
            _screens.Peek().LoadContent();
            base.LoadContent();
        }

        
        protected override void UnloadContent()
        {
            _screens.Peek().UnloadContent();
            base.UnloadContent();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        /// 
        public override void Update(GameTime gameTime)
        {
            // TODO: Add your update code here
            _screens.Peek().Update(gameTime);
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            RenderTarget2D transition;
            GameScreen screen = _screens.Peek();
            if (screen.ScreenState == ScreenState.TransitionOn || screen.ScreenState == ScreenState.TransitionOff)
            {
                PresentationParameters pp = GraphicsDevice.PresentationParameters;
                transition = new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, false, SurfaceFormat.Color, pp.DepthStencilFormat, pp.MultiSampleCount, RenderTargetUsage.DiscardContents);
                GraphicsDevice.SetRenderTarget(transition);
                GraphicsDevice.Clear(Color.Black);
                screen.Draw(gameTime);
                GraphicsDevice.SetRenderTarget(null);
                GraphicsDevice.Clear(Color.Transparent);
                _spriteBatch.Begin(0, BlendState.AlphaBlend);
                _spriteBatch.Draw(transition, Vector2.Zero, Color.White * screen.TransitionAlpha);
                _spriteBatch.End();
            }
            else
            {
                GraphicsDevice.Clear(Color.Transparent);
                screen.Draw(gameTime);
            }
        }
    }
}
